package middleware

import (
	"encoding/json"
	"errors"
	"github.com/gin-gonic/gin"
	"strconv"
	"time"
)

var (
	k12PassportUrl string
	ftPassportUrl  string
)

// 验证token
func HandlerTokenValidate() gin.HandlerFunc {
	return func(c *gin.Context) {
		accessToken := GetDahaiAccessToken(c)
		if accessToken == "" {
			abortRequest(c, 99999, "access_token not found", nil)
			return
		}
		uid, err := getK12Uid(c, accessToken)
		//// 产品线，默认k12
		//var uid int
		//var err error
		//productLine := GetBizProductLine(c)
		//if productLine == BizProductLineK12 || productLine == BizProductLineK12New || productLine == "" {
		//	// k12产品线
		//	uid, err = getK12Uid(c, accessToken)
		//} else if productLine == BizProductForeign || productLine == BizProductForeignNew {
		//	// 外教产品线
		//	uid, err = getFtUid(c, accessToken)
		//} else {
		//	abortRequest(c, 99999, "biz_product_line error", nil)
		//	return
		//}

		if err != nil || uid == 0 {
			return
		}

		setCtxUserId(c, uid)

		c.Next()
	}
}

func SetK12PassportAddr(url string) {
	k12PassportUrl = url
}

func SetFtPassportAddr(url string) {
	ftPassportUrl = url
}

// 用户id
func setCtxUserId(c *gin.Context, userId int) {
	c.Set(NvCtxUserId, userId)
}

type k12TokenValidateResult struct {
	Uid string `json:"uid"`
}

type k12TokenValidate struct {
	ErrorCode int                    `json:"error_code"`
	Message   string                 `json:"message"`
	Result    k12TokenValidateResult `json:"result"`
}

// 获取k12用户id
func getK12Uid(c *gin.Context, accessToken string) (int, error) {
	body := make(map[string]interface{})
	body["access_token"] = accessToken
	client := NewHttpClient(10 * time.Second)
	resp, err := client.JsonPost(c, k12PassportUrl, nil, nil, body)
	if err != nil {
		LogError(c, "k12_passport_error: "+err.Error())
		abortRequest(c, 99900, "internal error", nil)
		return 0, err
	}
	if resp == "" {
		err := errors.New("k12_passport_error: response empty")
		LogError(c, err)
		abortRequest(c, 99901, "internal error", nil)
		return 0, err
	}

	result := &k12TokenValidate{}
	err = json.Unmarshal([]byte(resp), &result)
	if err != nil {
		LogError(c, "k12_passport_error:"+err.Error())
		abortRequest(c, 99903, "internal error", nil)
		return 0, err
	}
	if result.ErrorCode != 0 {
		err := errors.New("k12_passport_error:" + result.Message)
		LogError(c, err)
		abortRequest(c, 99904, "token validate error", nil)
		return 0, err
	}
	if result.Result.Uid == "" {
		err := errors.New("k12_passport_error: user not found")
		LogError(c, err)
		abortRequest(c, 99994, "internal error", nil)
		return 0, err
	}

	uid, err := strconv.Atoi(result.Result.Uid)
	if err != nil {
		err := errors.New("k12_passport_error:" + err.Error())
		LogError(c, err)
		abortRequest(c, 99905, "internal error", nil)
		return 0, err
	}
	if uid <= 0 {
		err := errors.New("k12_passport_error: uid error")
		LogError(c, err)
		abortRequest(c, 99906, "internal error", nil)
		return 0, err
	}

	return uid, nil
}

type ftTokenValidateResult struct {
	Uid int `json:"uid"`
}

type ftTokenValidate struct {
	ErrorCode int                   `json:"error_code"`
	Message   string                `json:"message"`
	Result    ftTokenValidateResult `json:"result"`
}

// 获取外教用户id
func getFtUid(c *gin.Context, accessToken string) (int, error) {
	h := make(map[string]string)
	h["Content-Type"] = "application/json;charset=utf-8"
	h["uc-appid"] = "business-user-api"

	body := make(map[string]interface{})
	body["token"] = accessToken

	client := NewHttpClient(1 * time.Second)
	resp, err := client.JsonPost(c, ftPassportUrl, nil, h, body)
	if err != nil {
		LogError(c, "ft_passport_error: "+err.Error())
		abortRequest(c, 99900, "internal error", nil)
		return 0, err
	}
	if resp == "" {
		err := errors.New("ft_passport_error: response empty")
		LogError(c, err)
		abortRequest(c, 99901, "internal error", nil)
		return 0, err
	}

	result := &ftTokenValidate{}
	err = json.Unmarshal([]byte(resp), &result)
	if err != nil {
		LogError(c, "ft_passport_error:"+err.Error())
		abortRequest(c, 99902, "internal error", nil)
		return 0, err
	}
	if result.ErrorCode != 0 {
		err := errors.New("ft_passport_error:" + result.Message)
		LogError(c, err)
		abortRequest(c, 99903, "token validate error", nil)
		return 0, err
	}
	if result.Result.Uid <= 0 {
		err := errors.New("ft_passport_error: uid error")
		LogError(c, err)
		abortRequest(c, 99906, "internal error", nil)
		return 0, err
	}

	return result.Result.Uid, nil
}
